#include "AlOQRCode.h"


CAlOQRCode::CAlOQRCode()
{
}

CAlOQRCode::CAlOQRCode(CALStepItem* pStepItem)
{
	m_pStepItem = pStepItem;
}

CAlOQRCode::~CAlOQRCode()
{
}

void CAlOQRCode::test()
{

}

void CAlOQRCode::convert()
{
	if (m_pStepItem == NULL) return;

	try
	{
		CALSIOQRCode* pStepItem = (CALSIOQRCode*)m_pStepItem;

		Mat temp = m_srcMat;
		int ChanNum = m_srcMat.channels();
		if (temp.channels() == 3)
		{
			cvtColor(temp, temp, CV_RGB2GRAY);
		}

		Mat straight_barcode;
		string decoded_info;
		vector<Point> transform;
		const int count_experiments = 10;
		double transform_time = 0.0;
		bool result_detection = false;
		TickMeter total;
		QRCodeDetector qrcode;
		for (size_t i = 0; i < count_experiments; i++)
		{
			total.start();
			transform.clear();
			result_detection = qrcode.detect(temp, transform);
			total.stop();
			transform_time += total.getTimeSec();
			total.reset();
			if (!result_detection)
				continue;

			total.start();
			decoded_info = qrcode.decode(temp, transform, straight_barcode);
			total.stop();
			transform_time += total.getTimeSec();
			total.reset();
		}

		double fps = count_experiments / transform_time;
		if (!result_detection)
		{
			MapString info;
			info.strName = "reslut";
			info.strValue = "QR code not found";
			m_desInfoList.push_back(info);
			//cout << "QR code not found" << endl;
		}		
		else if (decoded_info.empty())
		{
			//cout << "QR code cannot be decoded" << endl;
			MapString info;
			info.strName = "reslut";
			info.strValue = "QR code cannot be decoded";
			m_desInfoList.push_back(info);
		}
		else
		{
			drawQRCodeContour(temp, transform);
			drawFPS(temp, fps);

			//cout << "Input  image file path: " << in_file << endl;
			//cout << "Output image file path: " << out_file << endl;
			//cout << "Size: " << color_src.size() << endl;
			//cout << "FPS: " << fps << endl;
			//cout << "Decoded info: " << decoded_info << endl;

			String str;

			MapString info;
			info.strName = "reslut";
			info.strValue = "success";
			m_desInfoList.push_back(info);

			MapString info1;
			info1.strName = "Size:";
			std_string_format(str, "%d", temp.size());
			info1.strValue = str;
			m_desInfoList.push_back(info1);

			MapString info2;
			info2.strName = "FPS:";
			std_string_format(str, "%f", fps);
			info2.strValue = str;
			m_desInfoList.push_back(info2);

			MapString info3;
			info3.strName = "Decoded info:";
			str = decoded_info;
			info3.strValue = str;
			m_desInfoList.push_back(info3);

			m_dstMat = temp;

			SetDstType(AL_DST_Mat_One | AL_DST_Info);
		}
	}
	catch (...)
	{

	}
}

void CAlOQRCode::convert(const Mat &src, Mat &dst)
{

}


void CAlOQRCode::drawQRCodeContour(Mat &color_image, vector<Point> transform)
{
	if (!transform.empty())
	{
		double show_radius = (color_image.rows  > color_image.cols)
			? (2.813 * color_image.rows) / color_image.cols
			: (2.813 * color_image.cols) / color_image.rows;
		double contour_radius = show_radius * 0.4;

		vector< vector<Point> > contours;
		contours.push_back(transform);
		drawContours(color_image, contours, 0, Scalar(211, 0, 148), cvRound(contour_radius));

		RNG rng(1000);
		for (size_t i = 0; i < 4; i++)
		{
			Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
			circle(color_image, transform[i], cvRound(show_radius), color, -1);
		}
	}
}

void CAlOQRCode::drawFPS(Mat &color_image, double fps)
{
	ostringstream convert;
	convert << cvRound(fps) << " FPS (QR detection)";
	putText(color_image, convert.str(), Point(25, 25), FONT_HERSHEY_DUPLEX, 1, Scalar(0, 0, 255), 2);
}